package com.guli.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 1/ 整合mybatis plus
 *   1) 导入依赖
 *    <dependency>
 *             <groupId>com.baomidou</groupId>
 *             <artifactId>mybatis-plus-boot-starter</artifactId>
 *             <version>3.4.3</version>
 *   </dependency>
 *   2) 配置
 *      1、配置数据源
 *         1)导入数据库的驱动
     *      <dependency>
     *        <groupId>mysql</groupId>
     *        <artifactId>mysql-connector-java</artifactId>
     *        <version>8.0.17</version>
     *      </dependency>
 *         2)再application.yml 配置数据源相关信息
 *
 *  2、配置mybatis-plus
 *          1）使用@MapperScan注解
 *          2）告诉mybatisplus 配置文件在哪
 *
 *  3.逻辑删除
 *      1）配置全局的逻辑删除规则（省略）
 *      2）配置上逻辑删除的组件（省略）
 *      3）给Bean加上逻辑删除注解 @TableLogic
 *
 *  4.JSR303
 *      1）给实体Bean添加校验注解:javax.validation.constraints，并定义自己的message提示
 *      2）开启校验功能 @Valid
 *      效果：校验错误以后会有默认的响应
 *      3)给校验Bean后紧跟一个BindingResult 就可以获取校验的结果
 *      4）分组校验（完成多场景的复杂校验）
 *          @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
 *          1.给注解标注什么情况需要校验 groups
 *          2.controller指定校验哪一个分组  public R save(@Validated({AddGroup.class})
 *          3.默认没有指定分组的校验注解 @NotBlank，在分组校验情况下不生效，只会在@Validated生效
 *      5）自定义校验
 *          1.编写一个自定义的校验注解 @interface ListValue
 *          2.编写一个自定义的校验器 ConstraintValidator
 *          3.关联自定义校验器和自定义校验注解
 *          @Documented
 *          @Constraint(
 *              validatedBy = {ListValueConstraintValidator.class}// 校验器
 *              可以指定多个不同的校验器，适配不通类型的校验
 *          )
 *          @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
 *          @Retention(RetentionPolicy.RUNTIME)
 *
 *
 *  5. 统一异常处理
 *      1）@ControllerAdvice
 *      2)编写异常处理类，使用@ControllerAdvice 注解
 *      3）使用@ExceptionHandler标注方法可以处理的异常
 *
 *  6.模版引擎
 *  1）。引入thymeleaf-stater,配置关闭缓存
 *  2）。静态资源都放在static文件下就可以按照路径直接访问
 *  3)。页面放在templates下，直接访问
 *     springboot 默认会找index.html
 *  4).页面修改不重启服务，服务器实时更新
 *    4.1）引入dev-tools
 *    4.2) 修改完页面 使用ctrl+shift+f9 重新自动编译页面
 *    如果是代码配置之类的还是推荐重启项目
 *
 *  7.整合Redis
 *   1）引入data-redis-starter
 *   2)简单配置Redis的host等信息
 *   3）使用Springboot自动配置好的StringRedisTemplate 来操作redis
 *   redis ： 键值对
 *  8.整合redisson作为分布式锁等功能的框架
 *   8.1)引入依赖
 *   8.2）配置redis
 *
 *  9.整合springcache 简化缓存开发
 *   9.1）引入依赖 spring-boot-starter-cache，spring-boot-starter-data-redis
 *   9.2) 写配置
 *       （1）、自动配置了哪些 ？
 *           CacheAutoConfigration会导入RedisCacheConfiguration;
 *           自动配置好了缓存管理器。
 *       （2）配置使用redis作为缓存
 *       （3）测试使用缓存
 *         注解如下：
 *          @Cacheable: Triggers cache population.  ：触发将数据保存到缓存的操作
 *
 *          @CacheEvict: Triggers cache eviction.   ：触发将数据从缓存删除的操作
 *
 *          @CachePut: Updates the cache without interfering with the method execution.  ： 不影响方法执行更新缓存。
 *
 *          @Caching: Regroups multiple cache operations to be applied on a method.     ：组合以上多个操作。
 *
 *          @CacheConfig: Shares some common cache-related settings at class-level.     ：在类级别共享缓存的相同配置。
 *
 *          1.开启缓存功能 @EnableCaching
 *          2.只需要使用注解就能完成缓存操作
 *        (4)原理
 *          CacheAutoConfigration->RedisCacheConfiguration->自动配置了缓存管理器 RedisCacheManager->
 *          初始化所有的缓存->每个缓存决定了使用什么配置->如果redisCacheConfiguration有就用已有的，没有就用默认
 *          配置->想改缓存的配置，只需要给容器中放一个RedisCacheConfiguration即可->就会应用到当前缓存管理器
 *          RedisCacheManager管理的所有缓存分区中。
 *
 *
 *
 *
 */
@MapperScan("com.guli.gulimall.product.dao")
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//(basePackages = "com.guli.gulimall.product.feign")
@EnableRedisHttpSession //开启spring session redis存储功能
public class GulimallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }

}
